package com.fmy.jurisdiction.modular.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fmy.jurisdiction.core.commons.consts.SystemConsts;
import com.fmy.jurisdiction.core.commons.kits.AdminPwdSecureKit;
import com.fmy.jurisdiction.core.commons.kits.BizExceptionKit;
import com.fmy.jurisdiction.core.commons.kits.MybatisPlusKit;
import com.fmy.jurisdiction.core.unusual.BizException;
import com.fmy.jurisdiction.modular.model.AdminUser;
import com.fmy.jurisdiction.modular.mapper.AdminUserMapper;
import com.fmy.jurisdiction.modular.service.IAdminDeptService;
import com.fmy.jurisdiction.modular.service.IAdminRoleService;
import com.fmy.jurisdiction.modular.service.IAdminUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author Mr.fmy
 * @since 2019-09-16
 */
@Service
@Slf4j
public class AdminUserServiceImpl extends ServiceImpl<AdminUserMapper, AdminUser> implements IAdminUserService {

    @Autowired
    private AdminUserMapper thisMapper;
    @Autowired
    private IAdminRoleService roleService;
    @Autowired
    private IAdminDeptService deptService;

    @Override
    public boolean addAdmin() {
        AdminUser user = new AdminUser();
        String pwd = "123456...";
        user.setId(SystemConsts.USER_ADMIN_ID).setUserName("超级管理员")
                .setUserLogin("admin").setSalt("admin")
                .setUserPhone("18888888888")
                .setPassword(AdminPwdSecureKit.md5(pwd, "admin"))
                .setRoles(SystemConsts.ROLE_ADMIN_ID.toString())
                .setDeptId(SystemConsts.DEPT_ADMIN_ID)
                .setCreateTime(LocalDateTime.now()).setCreateUser(SystemConsts.USER_ADMIN_ID);
        return thisMapper.addAdminUser(user) > 0;
    }

    @Override
    public int getPhoneCount(String phone) {
        return this.count(MybatisPlusKit.<AdminUser>q().eq(AdminUser.USER_PHONE, phone).eq(AdminUser.DEL_FLAG, false));
    }

    @Override
    public int getLoginCount(String userLogin) {
        return this.count(MybatisPlusKit.<AdminUser>q().eq(AdminUser.USER_LOGIN, userLogin).eq(AdminUser.DEL_FLAG, false));
    }

    @Override
    public boolean addUser(AdminUser user) {
        BizExceptionKit.throwBusiness(getLoginCount(user.getUserLogin()) > 0, "登录名已存在");
        BizExceptionKit.throwBusiness(getPhoneCount(user.getUserPhone()) > 0, "该手机号已被使用");
        user.setSalt(user.getUserLogin());//盐值
        String MD5Pwd = AdminPwdSecureKit.md5(user.getPassword(), user.getSalt());//加密密码
        user.setPassword(MD5Pwd);
        user.setCreateTime(LocalDateTime.now());//创建时间
        return this.save(user);
    }

    @Override
    public String getRoles(Integer userId) {
        return this.getObj(MybatisPlusKit.<AdminUser>q()
                .eq(AdminUser.ID, userId)
                .select(AdminUser.ROLES), user -> {
            return user.toString();
        });
    }

    @Override
    public boolean allocationRole(Integer userId, List<Integer> roleIds, Integer optionUser, Integer optionDeptId) {
        efficacy(userId, optionUser, optionDeptId);//公用验证
        String optionRoles = this.getRoles(optionUser);//获取操作人所有角色
        Integer optionUserLevel = roleService.getMaxLevel(optionRoles);//获取操作人最大角色层级
        StringBuffer sb = new StringBuffer();
        roleIds.forEach(item -> sb.append(item).append(","));
        String roleIdsStr = StrUtil.removeSuffix(sb.toString(), ",");
        BizExceptionKit.throwBusiness(optionUserLevel >= roleService.getMaxLevel(roleIdsStr), "无权分配某些角色、请尝试低等级角色");
        return this.update(MybatisPlusKit.<AdminUser>u()
                .eq(AdminUser.ID, userId)
                .set(AdminUser.ROLES, roleIdsStr)
                .set(AdminUser.MODIFY_TIME, LocalDateTime.now())
                .set(AdminUser.MODIFY_USER, optionUser));
    }

    @Override
    public boolean delUser(Integer userId, Integer optionUser, Integer optionDeptId) {
        efficacy(userId, optionUser, optionDeptId);//公用验证
        return this.update(MybatisPlusKit.<AdminUser>u()
                .set(AdminUser.USER_LOGIN, RandomUtil.randomString(11))
                .set(AdminUser.USER_PHONE, RandomUtil.randomString(11))
                .set(AdminUser.DEL_FLAG, true).set(AdminUser.MODIFY_TIME, LocalDateTime.now()).set(AdminUser.MODIFY_USER, optionUser)
                .eq(AdminUser.ID, userId));
    }

    @Override
    public IPage<Map<String, Object>> getUserPage(Integer cudeptId, String userName, Integer role, Integer deptId,
                                                  String phone, boolean delFlag, Integer page, Integer limit) {
        QueryWrapper<AdminUser> q = MybatisPlusKit.q();
        q.likeRight(StrUtil.isNotEmpty(userName), AdminUser.USER_NAME, userName)
                .eq(StrUtil.isNotEmpty(phone), AdminUser.USER_PHONE, phone)
                .like(role != null, AdminUser.ROLES, role)
                .eq(deptId != null, AdminUser.DEPT_ID, deptId)
                .eq(AdminUser.DEL_FLAG, delFlag);
        //查询部门所属子部门ID
        List<Integer> depts = deptService.fingByDeptSonId(cudeptId);
        depts.add(cudeptId);
        q.in(AdminUser.DEPT_ID, depts);
        return this.pageMaps(new Page<>(page, limit), q);
    }

    @Override
    public boolean mofidyEnable(boolean enable, Integer userId, Integer optionUser, Integer optionDeptId) {
        efficacy(userId, optionUser, optionDeptId);//公用验证
        return this.update(MybatisPlusKit.<AdminUser>u()
                .set(AdminUser.STATUS, enable)
                .set(AdminUser.MODIFY_TIME, LocalDateTime.now())
                .set(AdminUser.MODIFY_USER, optionUser)
                .eq(AdminUser.ID, userId));
    }

    @Override
    public String resetPwd(Integer userId, Integer optionUser, Integer optionDeptId) {
        efficacy(userId, optionUser, optionDeptId);//公用验证
        String pwd = RandomUtil.randomString(6);
        String salt = this.getObj(MybatisPlusKit.<AdminUser>q().eq(AdminUser.ID, userId).select(AdminUser.SALT), item -> item.toString());
        if (this.update(MybatisPlusKit.<AdminUser>u()
                .set(AdminUser.PASSWORD, AdminPwdSecureKit.md5(pwd, salt))
                .set(AdminUser.MODIFY_TIME, LocalDateTime.now())
                .set(AdminUser.MODIFY_USER, optionUser)
                .eq(AdminUser.ID, userId))) {
            return pwd;
        }
        throw new BizException("重置密码失败、请重试");
    }


    private void efficacy(Integer userId, Integer optionUser, Integer optionDeptId) {
        BizExceptionKit.throwBusiness(optionUser == userId, "不可操作自身");
        BizExceptionKit.throwBusiness(userId == SystemConsts.USER_ADMIN_ID, "该用户不可操作");
        //1、验证部门 不属于同部门/不属于子部门
        Integer deptId = this.getObj(MybatisPlusKit.<AdminUser>q().eq(AdminUser.ID, userId).select(AdminUser.DEPT_ID), item -> NumberUtil.parseInt(item.toString()));
        BizExceptionKit.throwBusiness(deptId != optionDeptId && deptService.findDeptVail(deptId, optionDeptId), "无权操作该用户");
    }
}
